package com.mxx.bu_yang.activity;

import android.Manifest;
import android.annotation.SuppressLint;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.FileProvider;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemChildClickListener;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.mxx.basic.activity.BaseActivity;
import com.mxx.basic.server.RetrofitHelper;
import com.mxx.basic.server.enums.RequestEnum;
import com.mxx.basic.server.retrofit.observer.DownloadObserver;
import com.mxx.basic.server.retrofit.observer.StringObserver;
import com.mxx.basic.utils.SPUtils;
import com.mxx.basic.utils.ToastUtils;
import com.mxx.bu_yang.BuildConfig;
import com.mxx.bu_yang.R;
import com.mxx.bu_yang.activity.off_line.BarcodeListNew1Activity;
import com.mxx.bu_yang.activity.on_line.GoodsCheckActivity;
import com.mxx.bu_yang.activity.on_line.GoodsManagerActivity;
import com.mxx.bu_yang.activity.on_line.WarehouseInActivity;
import com.mxx.bu_yang.activity.on_line.WarehouseOutActivity;
import com.mxx.bu_yang.adapter.HomeMenuAdapter;
import com.mxx.bu_yang.dialog.WarehouseListDialog;
import com.mxx.bu_yang.response.HomeMenuResponse;
import com.mxx.bu_yang.response.LoginInfoResponse;
import com.mxx.bu_yang.response.UpGradeResponse;
import com.mxx.bu_yang.utils.PermissionUtil;
import com.mxx.common.config.ConstantsConfig;
import com.mxx.common.response.BaseEntityResponse;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.ResponseBody;

public class MainActivity extends BaseActivity implements View.OnClickListener, OnItemChildClickListener {
    private TextView tv_login_out;
    private TextView tv_username;
    private FrameLayout fl_warehouse;
    private TextView tv_warehouse;
    private TextView tv_version;
    private RecyclerView rv_menu;
    private HomeMenuAdapter mMenuAdapter;
    private int fl_warehouse_height;
    private int fl_warehouse_width;
    private final String[] permissions = {
            Manifest.permission.WRITE_EXTERNAL_STORAGE
            , Manifest.permission.READ_EXTERNAL_STORAGE};

    /**
     * 获取当前页面的布局文件
     *
     * @return int
     */
    @Override
    public int getLayoutResId() {
        return R.layout.activity_main;
    }

    @Override
    protected boolean fitsSystemWindow() {
        return false;
    }

    @Override
    protected int getStatusBarColor() {
        return android.R.color.transparent;
    }

    @Override
    public void initView() {
        tv_login_out = findViewById(R.id.tv_login_out);
        tv_username = findViewById(R.id.tv_username);
        fl_warehouse = findViewById(R.id.fl_warehouse);
        tv_warehouse = findViewById(R.id.tv_warehouse);
        tv_version = findViewById(R.id.tv_version);
        rv_menu = findViewById(R.id.rv_menu);

        fl_warehouse.post(() -> fl_warehouse_height = fl_warehouse.getHeight());
        fl_warehouse.post(() -> fl_warehouse_width = fl_warehouse.getWidth());


        initMenu();
        checkUpGrade();
    }


    private void initMenu() {
        GridLayoutManager mManager = new GridLayoutManager(this, 2);
        rv_menu.setLayoutManager(mManager);
        RecyclerView.ItemDecoration decoration = new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(@NonNull Rect outRect, @NonNull View view
                    , @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                int mode = parent.getChildLayoutPosition(view);
                if (mode % 2 == 0) {
                    outRect.left = 10;
                    outRect.right = 0;
                    if (mode == 0) {
                        outRect.top = 30;
                    } else {
                        outRect.top = 0;
                    }
                } else if (mode % 2 == 1) {
                    outRect.left = 0;
                    outRect.right = 10;
                    if (mode == 1) {
                        outRect.top = 30;
                    } else {
                        outRect.top = 0;
                    }
                }
            }
        };
        rv_menu.addItemDecoration(decoration);
        mMenuAdapter = new HomeMenuAdapter(this, R.layout.adapter_home_menu);
        rv_menu.setAdapter(mMenuAdapter);
    }

    @Override
    public void initData() {
        super.initData();
        String version = getVersion();
        tv_version.setText(version);
        LoginInfoResponse response = getLoginInfo();
        loadUserInfoAndWarehouseInfo(response);
        loadMenu();

    }

    /**
     * 获取版本号
     *
     * @return 当前应用的版本号
     */

    public String getVersion() {

        try {

            PackageManager manager = this.getPackageManager();

            PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);

            String version = info.versionName;

            return "版本：" + version;

        } catch (Exception e) {

            e.printStackTrace();

            return "找不到版本号";

        }

    }


    private LoginInfoResponse getLoginInfo() {
        LoginInfoResponse response = null;
        String json = (String) SPUtils.get(this, "login_info", "");
        if (json != null && !json.isEmpty()) {
            response = new Gson().fromJson(json, new TypeToken<LoginInfoResponse>() {
            }.getType());
        }
        return response;
    }

    @SuppressLint("SetTextI18n")
    private void loadUserInfoAndWarehouseInfo(LoginInfoResponse response) {
        if (response == null) {
            return;
        }
        String userName = response.userName;
        if (userName != null && !userName.isEmpty()) {
            tv_username.setText("操作员：" + userName);
        }
        String wareName = response.wareName;
        if (wareName != null && !wareName.isEmpty()) {
            tv_warehouse.setText(wareName);
        }
    }

    private void loadMenu() {
        List<HomeMenuResponse> list = getHomeMenuList();
        mMenuAdapter.setList(list);
    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private List<HomeMenuResponse> getHomeMenuList() {
        List<HomeMenuResponse> list = new ArrayList<>();
        HomeMenuResponse response;
        response = new HomeMenuResponse();
        response.menu_id = 5;
        response.img_resource = getResources().getDrawable(R.drawable.home_in1);
        response.menu_name = "离线入库";
        list.add(response);

        response = new HomeMenuResponse();
        response.menu_id = 6;
        response.img_resource = getResources().getDrawable(R.drawable.home_out1);
        response.menu_name = "离线出库";
        list.add(response);

        response = new HomeMenuResponse();
        response.menu_id = 7;
        response.img_resource = getResources().getDrawable(R.drawable.home_back);
        response.menu_name = "出库货品回退";
        list.add(response);

        response = new HomeMenuResponse();
        response.menu_id = 3;
        response.img_resource = getResources().getDrawable(R.drawable.home_check);
        response.menu_name = "货品盘点";
        list.add(response);

        response = new HomeMenuResponse();
        response.menu_id = 4;
        response.img_resource = getResources().getDrawable(R.drawable.home_manager);
        response.menu_name = "货品管理";
        list.add(response);


        response = new HomeMenuResponse();
        response.menu_id = 1;
        response.img_resource = getResources().getDrawable(R.drawable.home_in);
        response.menu_name = "货品入库";
        list.add(response);

        response = new HomeMenuResponse();
        response.menu_id = 2;
        response.img_resource = getResources().getDrawable(R.drawable.home_out);
        response.menu_name = "货品出库";
        list.add(response);
        return list;
    }

    private void checkUpGrade() {
        String baseUrl = (String) SPUtils.get(this, ConstantsConfig.UPGRADE_URL, "");
        if (baseUrl == null || baseUrl.isEmpty()) {
            runOnUiThread(this::switchToLogin);
            return;
        }
        String action = "admin/api/app/version/upgrade";
        Map<String, String> params = new HashMap<>();
        String applyId = (String) SPUtils.get(MainActivity.this, ConstantsConfig.APPLY_ID, "");
        if (applyId == null || applyId.isEmpty()) {
            runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, "缺少必要参数"));
            switchToLogin();
            return;
        }
        params.put("applyId", applyId);
        new RetrofitHelper
                .Builder()
                .baseUrl(baseUrl)
                .appendUrl(action)
                .addParams(params)
                .build()
                .observable(RequestEnum.METHOD_POST_FORM)
                .subscribe(new StringObserver(MainActivity.this) {
                    @Override
                    protected void onSuccess(String json) {
                        handlerGradeJson(json);
                    }
                });
    }

    private void switchToLogin() {
        ToastUtils.showToast(this, "IP为空，请到登录页重新设置IP");
        SPUtils.put(this, "login_info", "");
        SPUtils.put(this, ConstantsConfig.BASE_URL, "");
        Intent mIntent = new Intent(this, LoginActivity.class);
        mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(mIntent);
        finish();
    }

    private void handlerGradeJson(String json) {
        BaseEntityResponse<UpGradeResponse> baseResponse = getBaseResponse(json);
        UpGradeResponse response = getUpGradeResposne(baseResponse);
        if (response == null) {
            ToastUtils.showToast(this, "服务器返回数据为空");
            return;
        }

        int locationVersionCode = getVersionCode();
        int versionSn = response.versionSn;
        if (versionSn < locationVersionCode || versionSn == locationVersionCode) {
            runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, "已是最新版本"));
            return;
        }

        boolean upgrade = response.upgrade;
        if (upgrade) {
            showForceUpGradeDialog(response);
        } else {
            showHintUpGradeResponse(response);
        }
    }

    private BaseEntityResponse<UpGradeResponse> getBaseResponse(String json) {
        if (json == null || json.isEmpty()) {
            return null;
        }
        Gson gson = new Gson().newBuilder().create();

        return gson.fromJson(json, new TypeToken<BaseEntityResponse<UpGradeResponse>>() {
        }.getType());
    }

    private UpGradeResponse getUpGradeResposne(BaseEntityResponse<UpGradeResponse> baseResponse) {
        if (baseResponse == null) {
            return null;
        }
        Object data = baseResponse.data;
        if (data == null) {
            return null;
        }
        Gson gson = new Gson().newBuilder().create();
        String json = gson.toJson(data);

        return gson.fromJson(json, new TypeToken<UpGradeResponse>() {
        }.getType());
    }

    /**
     * 获取版本号
     *
     * @return 当前应用的版本号
     */

    public int getVersionCode() {

        try {

            PackageManager manager = this.getPackageManager();

            PackageInfo info = manager.getPackageInfo(this.getPackageName(), 0);

            return info.versionCode;

        } catch (Exception e) {

            e.printStackTrace();
            return 1;

        }
    }

    private void showForceUpGradeDialog(UpGradeResponse response) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder
                .setIcon(R.mipmap.ic_launcher)
                .setTitle("App升级")
                .setMessage(response.upgradeWen)
                .setPositiveButton("升级", (dialog, which) -> {
                    dialog.dismiss();
                    checkPermissions(response);
                })
                .setOnKeyListener((dialog, keyCode, event) -> keyCode == KeyEvent.KEYCODE_BACK)
                .setCancelable(false)
                .create()
                .show();
    }


    private void showHintUpGradeResponse(UpGradeResponse response) {
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder
                .setIcon(R.mipmap.ic_launcher)
                .setTitle("App升级")
                .setMessage(response.upgradeWen)
                .setPositiveButton("升级", (dialog, which) -> {
                    dialog.dismiss();
                    checkPermissions(response);
                })
                .setNegativeButton("忽略", (dialog, which) -> dialog.dismiss())
                .setOnKeyListener((dialog, keyCode, event) -> keyCode == KeyEvent.KEYCODE_BACK)
                .setCancelable(false)
                .create()
                .show();

    }

    private void checkPermissions(UpGradeResponse response) {
        PermissionUtil.getInstance().requestPermission(MainActivity.this, new PermissionUtil.IPermissionListener() {
            @Override
            public void allPermissionGranted() {
                doSomething(true, response);
            }

            @Override
            public void partPermissionRefuse() {
                doSomething(false, response);
            }
        }, permissions);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        PermissionUtil.getInstance().handlerActivityResult(requestCode, grantResults);
    }

    private void doSomething(boolean hasPermission, UpGradeResponse response) {
        if (!hasPermission) {
            runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, "权限被拒绝"));
        }
        String url = response.upgradeUrl;
//        openBrowser(MainActivity.this, url);
        startDownload(url);
    }

    private void openBrowser(Context context, String url) {
        if (url == null || url.isEmpty()) {
            runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, "下载路径不存在"));
            return;
        }
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(Uri.parse(url));
        // 注意此处的判断intent.resolveActivity()可以返回显示该Intent的Activity对应的组件名
        // 官方解释 : Name of the component implementing an activity that can display the intent
        if (intent.resolveActivity(context.getPackageManager()) != null) {
            final ComponentName componentName = intent.resolveActivity(context.getPackageManager());
            // 打印Log   ComponentName到底是什么
            context.startActivity(Intent.createChooser(intent, "请选择浏览器"));
        } else {
            Toast.makeText(context.getApplicationContext(), "请下载浏览器", Toast.LENGTH_SHORT).show();
        }
    }

    private void startDownload(String url) {
        if (url == null || url.isEmpty()) {
            runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, "下载路径不存在"));
            return;
        }
        ProgressDialog dialog = creteProgressDialog();
        int index = url.lastIndexOf("/");
        int length = url.length();
        String baseUrl = url.substring(0, index + 1);
        String action = url.substring(index + 1, length);
        new RetrofitHelper
                .Builder()
                .baseUrl(baseUrl)
                .appendUrl(action)
                .build()
                .observable(RequestEnum.METHOD_DOWNLOAD)
                .subscribe(new DownloadObserver() {
                    @Override
                    protected void onSuccess(ResponseBody body) {
                        String path = getParentFilePath()
                                + File.separator
                                + MainActivity.this.getResources().getString(R.string.app_name)
                                + "_"
                                + getVersionCode()
                                + ".apk";
                        writeToDisk(dialog, body, path);

                    }

                    @Override
                    protected void onFailed(Integer code, String msg) {
                        runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, msg));
                    }
                });
    }

    private ProgressDialog creteProgressDialog() {
        ProgressDialog dialog = new ProgressDialog(MainActivity.this);
        dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        dialog.setIcon(R.mipmap.ic_launcher);
        dialog.setTitle("下载中......");
        dialog.setCancelable(false);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setMax(100);
        dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                return keyCode == KeyEvent.KEYCODE_BACK;
            }
        });
        return dialog;
    }

    private File getTargetFile(String path) {
        try {
            String parentFilePath = path.substring(0, path.lastIndexOf(File.separator) + 1);
            File parentFile = new File(parentFilePath);
            if (!parentFile.exists()) {
                parentFile.mkdirs();
            }
            File file = new File(path);
            if (!file.exists()) {
                file.createNewFile();
            }
            return file;
        } catch (Exception e) {
            return null;
        }
    }

    private void writeToDisk(ProgressDialog dialog, ResponseBody body, String path) {
        new Thread(() -> {
            runOnUiThread(dialog::show);
            InputStream inputStream = body.byteStream();
            File targetFile = getTargetFile(path);
            if (inputStream == null || targetFile == null) {
                if (inputStream == null) {
                    runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, "获取文件写入内容失败"));
                }
                if (targetFile == null) {
                    runOnUiThread(() -> ToastUtils.showToast(MainActivity.this, "获取目标文件失败"));
                }
                return;
            }

            try {
                FileOutputStream outputStream = new FileOutputStream(targetFile);
                byte[] bytes = new byte[1024];
                int len;
                long total = 0L;
                long contentLength = body.contentLength();
                while ((len = inputStream.read(bytes)) != -1) {
                    outputStream.write(bytes, 0, len);
                    total += len;
                    int progress = (int) (total * 100 / contentLength);
                    dialog.setProgress(progress);
                }
                if (inputStream != null) {
                    inputStream.close();
                }
                if (outputStream != null) {
                    outputStream.close();
                }
                runOnUiThread(() -> {
                    ToastUtils.showToast(MainActivity.this, "下载完成\n开始自动安装");
                    dialog.dismiss();
                    new Thread(() -> installApk(MainActivity.this, targetFile)).start();
                });

            } catch (FileNotFoundException e) {
                e.printStackTrace();
                runOnUiThread(() -> {
                    dialog.dismiss();
                    ToastUtils.showToast(MainActivity.this, e.getMessage());
                });

            } catch (IOException e) {
                e.printStackTrace();
                runOnUiThread(() -> {
                    dialog.dismiss();
                    ToastUtils.showToast(MainActivity.this, e.getMessage());
                });
            }

        }).start();


    }

    private void installApk(Context context, File file) {
        try {
            Intent mIntent = new Intent(Intent.ACTION_VIEW);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                mIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                mIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file);
                mIntent.setDataAndType(uri, "application/vnd.android.package-archive");
            } else {
                mIntent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
                mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            }
            context.startActivity(mIntent);
        } catch (Exception e) {
            e.printStackTrace();
            runOnUiThread(() -> ToastUtils.showToast(context, e.getMessage()));
        }

    }

    private String getParentFilePath() {
        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
        if (sdCardExist) {
            sdDir = getExternalFilesDir("");
        }
        return sdDir != null ? sdDir.toString() : null;
    }

    private void writeResponseBodyToDisk(ProgressDialog dialog, ResponseBody body) {
        new Thread(() -> {
            runOnUiThread(dialog::show);
            try {

                InputStream inputStream = body.byteStream();

            } catch (Exception e) {
                e.printStackTrace();
                runOnUiThread(() -> {
                    ToastUtils.showToast(MainActivity.this, e.getMessage());
                    dialog.dismiss();
                });
            }
            runOnUiThread(dialog::dismiss);
        }).start();

    }


    @Override
    public void initListener() {
        super.initListener();
        tv_login_out.setOnClickListener(this);
        mMenuAdapter.setOnItemChildClickListener(this);
    }

    @Override
    public void onClick(View view) {
        if (view.getId() == R.id.fl_warehouse) {
            Log.i("TAG", "do  nothing");
            showWareHouseListDialog();
        }
        if (view.getId() == R.id.tv_login_out) {
            Log.i("TAG", "do  nothing");
            loginOut();
        }

    }

    private void showWareHouseListDialog() {
        int[] location = new int[2];
        fl_warehouse.getLocationOnScreen(location);
        fl_warehouse.getLocationOnScreen(location);
        WarehouseListDialog dialog = new WarehouseListDialog(fl_warehouse_width, location[0]
                , fl_warehouse_height, location[1], false);

        Bundle mBundle = new Bundle();

        dialog.setArguments(mBundle);
        dialog.setBackDataListener(response -> {
            if (response == null) {
                ToastUtils.showToast(MainActivity.this, "信息为空");
                return;
            }
            String name = response.name;
            tv_warehouse.setText(name);
        });
        dialog.show(this.getSupportFragmentManager()
                , "BaseDialog");
    }

    private void loginOut() {
        SPUtils.put(this, "login_info", "");
        Intent mIntent = new Intent(this, LoginActivity.class);
        mIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(mIntent);
        finish();
    }

    @Override
    public void onItemChildClick(@NonNull BaseQuickAdapter adapter, @NonNull View view,
                                 int position) {
        if (view.getId() == R.id.ll_menu) {
            HomeMenuResponse response = (HomeMenuResponse) adapter.getItem(position);
            int menu_id = response.menu_id;
            skipToTargetUiById(menu_id);
        }
    }

    private void skipToTargetUiById(int menu_id) {
        //id 1货品入库  2货品出库 3货品盘点  4货品管理 5离线入库 6离线出库 7出库货品回退
        if (menu_id == 1 || menu_id == 2) {
            ToastUtils.showToast(this, "暂未开放");
            return;
        }
        Class<?> targetClass = getTargetClass(menu_id);
        if (targetClass == null) {
            ToastUtils.showToast(this, "未找到目标路径");
            return;
        }
        Intent mIntent = new Intent(this, targetClass);
        if (menu_id == 5 || menu_id == 6 || menu_id == 7) {
            //3 货品盘点  4 货品管咯
            Bundle mBundle = new Bundle();
            mBundle.putSerializable("menu_id", menu_id);
            mIntent.putExtras(mBundle);
        }
        startActivity(mIntent);
    }

    private Class<?> getTargetClass(int menu_id) {
        Class<?> targetClass = null;
        if (menu_id == 1) {
            targetClass = WarehouseInActivity.class;
        }
        if (menu_id == 2) {
            targetClass = WarehouseOutActivity.class;
        }
        if (menu_id == 3) {
            targetClass = GoodsCheckActivity.class;
        }
        if (menu_id == 4) {
            targetClass = GoodsManagerActivity.class;
        }
        if (menu_id == 5) {
            targetClass = BarcodeListNew1Activity.class;
        }
        if (menu_id == 6) {
            targetClass = BarcodeListNew1Activity.class;
        }
        if (menu_id == 7) {
            targetClass = BarcodeListNew1Activity.class;
        }
        return targetClass;
    }
}